package com.GZHU.fisco;

import com.GZHU.entity.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple4;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Slf4j
public class BlockChainClient {
    // 模型记录上链，参数：为合约对象，需要上链的记录
    public static boolean record_to_chain(Data_upload data_upload,model_record record){
        boolean res=true;
        try {
            data_upload.inster_model_record(record.getModel_id(),
                    record.getProducer_id(),
                    record.getCertifer_id(),
                    record.getVerifyer_id());
            log.info("模型记录上链成功");
        }catch (Exception e){
            res=false;
            log.info("模型记录上链失败");
        }
        return res;
    }
    // 模型状态变更上链
    public static boolean state_to_chain(Data_upload data_upload,state_change state){
        boolean res=true;
        try {
            data_upload.inster_state_change(state.getModel_id(),
                    state.getTime(),
                    state.getChange_type(),
                    state.getOperator_id());
            System.out.println("模型状态变更上链成功");
        }catch (Exception e){
            res=false;
            System.out.println("模型状态变更上链失败");
        }
        return res;
    }
    // 部署合约上链,返回链上合约地址
    public static String deploy_contract(){
        @SuppressWarnings("resource")
        ApplicationContext context =
                new ClassPathXmlApplicationContext("fisco-config.xml");
        BcosSDK bcosSDK = context.getBean(BcosSDK.class);
        Client client=bcosSDK.getClient(1);
        CryptoKeyPair credential = client.getCryptoSuite().getCryptoKeyPair();
        String address=null;
        Data_upload res=null;
        try {
            res=Data_upload.deploy(client,credential);
            System.out.println("合约部署成功");
            System.out.println("合约部署地址："+res.getContractAddress());
            address=res.getContractAddress();
        }catch (Exception e){
            System.out.println("合约部署失败");
        }
        return address;
    }
    //加载已经部署上链的合约,参数为合约已部署合约的地址，返回一个合约对象
    public static Data_upload load_contract(String address){
        @SuppressWarnings("resource")
        ApplicationContext context =
                new ClassPathXmlApplicationContext("fisco-config.xml");
        BcosSDK bcosSDK = context.getBean(BcosSDK.class);
        Client client=bcosSDK.getClient(1);
        CryptoKeyPair credential = client.getCryptoSuite().getCryptoKeyPair();
        Data_upload res=null;
        try {
            res=Data_upload.load(address,client,credential);
            log.info("合约加载成功");
        }catch (Exception e){
            log.info("合约加载失败");
        }
        return res;
    }
    // 模型记录查询，参数为合约对象，模型号，返回模型记录信息
    public static HashMap<String,String> query_record(Data_upload data_upload, String model_id){
        HashMap<String,String> res=new HashMap<String,String>();
        try {
            Tuple4<List<String>, List<String>, List<String>, List<String>> res0=data_upload.query_model_record(model_id);
            res.put("模型号", res0.getValue1().toString());
            res.put("生产者", res0.getValue2().toString());
            res.put("认证者", res0.getValue3().toString());
            res.put("审核人", res0.getValue4().toString());
            log.info("模型记录查询成功");
        }catch (Exception e){
            log.info("模型记录查询失败");
        }
        return res;
    }
    // 模型状态查询，参数为合约对象，模型号，返回模型状态信息
    public static ArrayList<String> query_state(Data_upload data_upload, String model_id){
        ArrayList<String> res= new ArrayList<String>();
        try {
            Tuple4<List<String>, List<String>, List<String>, List<String>> res0=data_upload.query_state_change(model_id);
            int j=res0.getValue1().size();
            for (int i = 0; i < j; i++) {
                HashMap<String,String> one=new HashMap<String,String>();
                one.put("model_id",res0.getValue1().get(i));
                one.put("time",res0.getValue2().get(i));
                one.put("type",res0.getValue3().get(i));
                one.put("operator",res0.getValue4().get(i));
                String json="";
                try {
                    json = new ObjectMapper().writeValueAsString(one);
                }catch (Exception e){
                    log.info("模型状态无法转化为json");
                }
                res.add(json);
            }
            log.info("模型状态查询成功");
        }catch (Exception e){
            log.info("模型状态查询失败");
        }
        return res;
    }
//    @SneakyThrows
//    public static void main(String[] args) {
//        String address=deploy_contract();
////        System.out.println(address);？
////        String address="0x41cab083900c9cf089519394c07b753e85d1573c";
//        Data_upload data_upload=load_contract(address);
////
////        model_record arecord=new model_record();
////        arecord.setModel_id("001");
////        arecord.setCertifer_id("认证人123");
////        arecord.setProducer_id("生产者123");
////        arecord.setVerifyer_id("审核人123");
//////
////        state_change astate=new state_change();
////        astate.setModel_id("001");
////        astate.setChange_type("训练");
////        astate.setTime("10:00:00");
////        astate.setOperator_id("明");
////
////        state_change bstate=new state_change();
////        bstate.setModel_id("001");
////        bstate.setChange_type("使用");
////        bstate.setTime("19:20:20");
////        bstate.setOperator_id("老王");
////        record_to_chain(data_upload,arecord);
////        state_to_chain(data_upload,astate);
////        state_to_chain(data_upload,bstate);
//        HashMap<String,String> res=query_record(data_upload,"001");
//        System.out.println(res);
////
//        ArrayList<String> res0=query_state(data_upload,"001");
//        System.out.println(res0);
//        System.out.println(address);
////        log.info("dsf");
//
//
//
//    }

}
